package com.carp.shard.plugin.visitor;


import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
import com.carp.shard.plugin.constant.ReadType;
import com.carp.shard.plugin.constant.WriteType;
import com.carp.shard.plugin.strategy.AbstractShardStrategy;
import com.carp.shard.plugin.strategy.ShardStrategyContext;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.mapping.BoundSql;

/**
 * 用于替换表名的 Visitor (MySQL)
 *
 * @author lile
 * @since 2024/5/22
 */
@Getter
@RequiredArgsConstructor
public class MySqlReplaceTableNameVisitor extends MySqlASTVisitorAdapter {

    private final BoundSql boundSql;
    private boolean anyReplaced = false;
    private ReadType finalReadType = ReadType.OLD;
    private WriteType finalWriteType = WriteType.OLD;

    @Override
    public boolean visit(SQLExprTableSource x) {
        AbstractShardStrategy shardStrategy = ShardStrategyContext
                .getStrategyByTableName(x.getExpr().toString());
        boolean replaced = shardStrategy.replaceTableName(x, boundSql);
        processFlag(replaced, shardStrategy);
        return true;
    }

    private void processFlag(boolean replaced, AbstractShardStrategy shardStrategy) {
        anyReplaced = replaced || anyReplaced;

        if (finalReadType == ReadType.OLD) {
            finalReadType = shardStrategy.getReadType();
        }

        if (finalWriteType == WriteType.OLD) {
            finalWriteType = shardStrategy.getWriteType();
        }
    }

}
